#include "sk_game_level.h"
#include "sk_creation_params.h"
#include "sk_game_element_by_string.h"

#include "sk_box_shape.h"
#include "sk_circle_shape.h"
#include "sk_triangle_shape.h"

#include "sk_game_forwards.h"

#include <QObject>
#include <QDomElement>
#include <QDomDocument>

namespace sk
{

GameLevel::GameLevel()
{
    _name = QObject::tr("unnamed");
    shapes.reserve(16);
    dropShapes.reserve(16);
    w = 360;
    h = 640;
    gx = 0;
    gy = 9.8;
    num = 457;
    color = QColor(Qt::white);

}

GameLevel::~GameLevel()
{
}

QString GameLevel::name() const
{
    return _name;
}

void GameLevel::setName(QString name)
{
    _name = name;
}

GameShapeRef GameLevel::addShape(void* params)
{
    SimpleItemParam * p = static_cast<SimpleItemParam*>(params);

    QVector <GameShapeRef> * c = p->drop ? &dropShapes : &shapes;
    if (p->type == IT_SIMPLE_BOX)
    {
        c->push_back(GameShapeRef(new BoxShape()));
        c->back()->setData(static_cast<SimpleBoxParam*>(p->param));
        return c->back();
    }
    if (p->type == IT_SIMPLE_CIRCLE)
    {
        c->push_back(GameShapeRef(new CircleShape()));
        c->back()->setData(static_cast<SimpleCircleParam*>(p->param));
        return c->back();
    }
    if (p->type == IT_SIMPLE_TRIANGLE)
    {
        c->push_back(GameShapeRef(new TriangleShape()));
        c->back()->setData(static_cast<SimpleTriangleParam*>(p->param));
        return c->back();
    }
    return GameShapeRef();
}

void GameLevel::serialize(QDomDocument * doc, QDomElement * e)
{
    e->setAttribute("name", name());

    QDomElement shapesElement = doc->createElement("shapes");

    for (int i = 0; i < shapes.size(); ++i)
    {
        QDomElement ee = doc->createElement("shape");
        ee.setAttribute("type", shapes[i]->xmlType());
        shapes[i]->serialize(doc, &ee);
        shapesElement.appendChild(ee);
    }
    e->appendChild(shapesElement);


    QDomElement dropShapesElement = doc->createElement("dropShapes");

    for (int i = 0; i < dropShapes.size(); ++i)
    {
        QDomElement ee = doc->createElement("shape");
        ee.setAttribute("type", dropShapes[i]->xmlType());
        dropShapes[i]->serialize(doc, &ee);
        dropShapesElement.appendChild(ee);
    }
    e->appendChild(dropShapesElement);
}

GameShape * GameLevel::shape(QDomElement * s)
{
    QString type = s->attribute("type");
    return GameElementByString::gameShape(type);

}

bool GameLevel::deserialize(QDomElement * e)
{
    // todo : THINK, REFACTOR, REWRITE, this is ver POOR functioin, only for current purposes
    setName(e->attribute("name"));
    for (int i = 0; i < e->childNodes().count(); ++i)
    {
        QDomElement ee = e->childNodes().at(i).toElement();
        if (ee.tagName() == "shapes")
        {
            for (int j = 0; j < ee.childNodes().count(); ++j)
            {
                QDomElement s = ee.childNodes().at(j).toElement();
                GameShape * ss = shape(&s);
                if (0 == ss)
                {
                    return false;
                }
                shapes.push_back(GameShapeRef(ss));
                if (!ss->deserialize(&s))
                {
                    return false;
                }
            }
        }
        else
        if (ee.tagName() == "dropShapes")
        {
            int n = ee.childNodes().count();
            for (int j = 0; j < n; ++j)
            {
                QDomElement s = ee.childNodes().at(j).toElement();
                GameShape * ss = shape(&s);
                if (0 == ss)
                {
                    return false;
                }
                dropShapes.push_back(GameShapeRef(ss));
                if (!ss->deserialize(&s))
                {
                    return false;
                }
            }
        }
    }
    return true;
}

}
